/// @Classname : HcSwitch
/// @Author :
/// @Time : 2023-05-15 10:24
/// @Description : //todo

import 'package:flutter/material.dart';
import 'package:hc_ui/utils/hc_color_util.dart';

import '../../constants/hc_size.dart';

//展示组件的位置 none不显示 track轨道上 thumb 按钮上  ,all全部
enum HcSwitchShowPosition { none, track, thumb, all }

typedef HcSwitchChange = Future<bool?> Function(bool value);

class HcSwitch extends StatefulWidget {
  //点击后的回调
  final HcSwitchChange onChanged;

  //当前状态
  final bool value;

  //是否禁用
  final bool disabled;

  //激活状态下按钮颜色
  final Color? activeColor;

  //激活状态下轨道颜色
  final Color? activeTrackColor;

  //关闭状态下按钮颜色
  final Color? inactiveThumbColor;

  //关闭状态下轨道颜色
  final Color? inactiveTrackColor;

  //按钮的组件
  final Widget? thumbWidget;

  //是否展示加载中
  final bool showLoading;

  //按钮大小
  final double size;

  //组件和按钮的圆角
  final double? radius;

  //轨道和按钮间的距离
  final double padding;

  //激活状态显示的组件
  final Widget? activeWidget;

  //未激活状态显示的组件
  final Widget? inactiveWidget;

  //显示组件的位置
  final HcSwitchShowPosition showPosition;

  //动画时间
  final Duration? duration;

  const HcSwitch(
      {Key? key,
      required this.onChanged,
      this.value = false,
      this.disabled = false,
      this.activeColor,
      this.activeTrackColor,
      this.inactiveThumbColor,
      this.inactiveTrackColor,
      this.thumbWidget,
      this.showLoading = false,
      this.size = 20,
      this.radius,
      this.duration,
      this.padding = 3,
      this.activeWidget,
      this.inactiveWidget,
      this.showPosition = HcSwitchShowPosition.none})
      : super(key: key);

  @override
  State<HcSwitch> createState() => _HcSwitchState();
}

class _HcSwitchState extends State<HcSwitch> {
  //手指滑动的距离
  double dragDistance = 0;

  //当前选中的状态
  bool value = false;

  //当前是否展示加载中效果
  bool showLoading = false;

  //圆角
  double radius = 0;

  //需要展示的 组件列表
  List<Widget> widgetList = List.empty();

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    value = widget.value;
    radius = widget.radius ?? (widget.size + widget.padding * 2) / 2;
    widgetList = [
      widget.activeWidget ?? const Text(""),
      widget.inactiveWidget ?? const Text(""),
    ];

    if (widget.showPosition == HcSwitchShowPosition.all) {
      widgetList = widgetList.reversed.toList();
    }
  }

  @override
  void didUpdateWidget(HcSwitch oldWidget) {
    super.didUpdateWidget(oldWidget);
    widgetList = [
      widget.activeWidget ?? const Text(""),
      widget.inactiveWidget ?? const Text(""),
    ];
    if (widget.showPosition == HcSwitchShowPosition.all) {
      widgetList = widgetList.reversed.toList();
    }
    setState(() {
      value = widget.value;
      radius = widget.radius ?? (widget.size + widget.padding * 2) / 2;
      widgetList = widgetList;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Semantics(
      toggled: value,
      child: Container(
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(radius),
        ),
        child: Stack(
          children: [_trackWidget(), _thumbWidget()],
        ),
      ),
    );
  }

  //轨道构建组件
  Widget _trackWidget() {
    Color trackColor = value
        ? (widget.activeTrackColor ?? Theme.of(context).primaryColor)
        : (widget.inactiveTrackColor ?? Colors.grey);
    return GestureDetector(
      excludeFromSemantics: true,
      onTap: _onTap,
      child: AnimatedContainer(
        width: widget.size * 2 + widget.padding * 2,
        height: widget.size + widget.padding * 2,
        decoration: BoxDecoration(
          color: trackColor.withOpacity(widget.disabled
              ? HcSize.defaultSwitchDisableOpacity
              : HcSize.defaultSwitchOpacity),
          borderRadius: BorderRadius.circular(radius),
        ),
        duration: widget.duration ?? const Duration(milliseconds: 500),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: widget.showPosition == HcSwitchShowPosition.track ||
                  widget.showPosition == HcSwitchShowPosition.all
              ? widgetList
                  .map((child) => _buildListItem(child, trackColor))
                  .toList()
              : [const SizedBox(), const SizedBox()],
        ),
      ),
    );
  }

  Widget _buildListItem(Widget child, Color color) {
    final ThemeData theme = Theme.of(context);

    final TextStyle effectiveTextStyle = theme.useMaterial3
        ? theme.textTheme.titleMedium!
        : theme.primaryTextTheme.titleMedium!;
    TextStyle textStyle =
        effectiveTextStyle.copyWith(color: color, fontSize: widget.size / 2);
    switch (ThemeData.estimateBrightnessForColor(color)) {
      case Brightness.dark:
        textStyle = textStyle.copyWith(color: theme.primaryColorLight);
        break;
      case Brightness.light:
        textStyle = textStyle.copyWith(color: theme.primaryColorDark);
        break;
    }
    return SizedBox(
      width: widget.size,
      height: widget.size,
      child: Center(
        child: IconTheme(
          data: theme.iconTheme
              .copyWith(color: textStyle.color, size: widget.size / 2),
          child: DefaultTextStyle(
            style: textStyle,
            child: child,
          ),
        ),
      ),
    );
  }

  //顶部按钮组件
  Widget _thumbWidget() {
    Color bgColor = value
        ? (widget.activeColor ?? Theme.of(context).colorScheme.secondary)
        : (widget.inactiveThumbColor ?? Colors.white);
    //动画组件
    return AnimatedPositioned(
        left: !value ? 0 : 1 * widget.size,
        duration: widget.duration ?? const Duration(milliseconds: 100),
        child: GestureDetector(
          excludeFromSemantics: true,
          //滑动开始
          onHorizontalDragStart: _onHorizontalDragStart,
          //滑动更新
          onHorizontalDragUpdate: _onHorizontalDragUpdate,
          //滑动结束
          onHorizontalDragEnd: _onHorizontalDragEnd,
          //点击事件
          onTap: _onTap,
          child: AnimatedContainer(
            width: widget.size,
            height: widget.size,
            margin: EdgeInsets.all(widget.padding),
            decoration: BoxDecoration(
                color: bgColor, borderRadius: BorderRadius.circular(radius)),
            duration: const Duration(milliseconds: 300),
            child: Center(
              child: !showLoading
                  ? widget.thumbWidget ??
                      (widget.showPosition.index <
                              HcSwitchShowPosition.thumb.index
                          ? const Text("")
                          : widgetList
                              .map((child) => _buildListItem(child, bgColor))
                              .toList()[value ? 1 : 0])
                  : Padding(
                      padding: EdgeInsets.all(widget.size / 5),
                      child: CircularProgressIndicator(
                        strokeWidth: widget.size / 20,
                        color: HcColorUtil.needLightColor(bgColor)
                            ? Theme.of(context).primaryColorDark
                            : Theme.of(context).primaryColorLight,
                      ),
                    ),
            ),
          ),
        ));
  }

  //点击事件
  void _onTap() {
    dragDistance = widget.size * (value ? -1 : 1);
    changeState();
  }

  //手指结束
  void _onHorizontalDragEnd(details) => changeState();

  //手指更新
  void _onHorizontalDragUpdate(value) => dragDistance = value.localPosition.dx;

  //手指滑动开始
  void _onHorizontalDragStart(value) => dragDistance = 0;

  changeState() async {
    if (widget.disabled) return;
    if ((value && dragDistance > 0) || (!value && dragDistance < 0)) {
      return;
    }
    //如果参数不为空
    if (widget.showLoading) {
      setState(() {
        showLoading = true;
      });
    }
    bool result = !value;
    try {
      result = (await widget.onChanged.call(value)) ?? !value;
    } finally {}
    setState(() {
      value = result;
      showLoading = false;
    });
  }
}
